from flask import request, jsonify, g
from flask_jwt_extended import jwt_required
import datetime
from bson import ObjectId

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required
from app.schemas.medical_order import MedicalOrderSchema, MedicalOrderUpdateSchema, MedicalOrderQuerySchema
from app.utils.common import normalize_data, paginate, generate_id

@api_bp.route('/medical-orders', methods=['GET'])
@jwt_required()
@permission_required('medical_order:read')
def get_medical_orders():
    """获取医嘱列表"""
    # 获取查询参数
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'createdAt')
    order = request.args.get('order', 'desc')
    
    # 构建查询条件
    query = {}
    
    # 按患者ID筛选
    patient_id = request.args.get('patientId')
    if patient_id:
        query['patientId'] = patient_id
    
    # 按医生ID筛选
    doctor_id = request.args.get('doctorId')
    if doctor_id:
        query['doctorId'] = doctor_id
    
    # 按科室ID筛选
    department_id = request.args.get('departmentId')
    if department_id:
        query['departmentId'] = department_id
    
    # 按医疗记录ID筛选
    medical_record_id = request.args.get('medicalRecordId')
    if medical_record_id:
        query['medicalRecordId'] = medical_record_id
    
    # 按类型筛选
    order_type = request.args.get('type')
    if order_type and order_type != 'all':
        query['type'] = order_type
    
    # 按状态筛选
    status = request.args.get('status')
    if status and status != 'all':
        query['status'] = status
    
    # 按日期范围筛选
    start_date = request.args.get('startDate')
    if start_date:
        try:
            start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
            if 'createdAt' not in query:
                query['createdAt'] = {}
            query['createdAt']['$gte'] = start_date
        except ValueError:
            pass
    
    end_date = request.args.get('endDate')
    if end_date:
        try:
            end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
            # 将结束日期设为当天的结束时间
            end_date = end_date.replace(hour=23, minute=59, second=59)
            if 'createdAt' not in query:
                query['createdAt'] = {}
            query['createdAt']['$lte'] = end_date
        except ValueError:
            pass
    
    # 确定排序
    sort_direction = -1 if order.lower() == 'desc' else 1
    
    # 获取数据
    orders_cursor = mongo.db.medical_orders.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(orders_cursor, page, limit)
    
    # 标准化数据并添加患者和医生信息
    orders = []
    for order in paginated_data['items']:
        # 获取患者信息
        patient_name = ''
        if 'patientId' in order:
            patient_id = order['patientId']
            if isinstance(patient_id, str) and ObjectId.is_valid(patient_id):
                patient_id = ObjectId(patient_id)
            patient = mongo.db.patients.find_one({'_id': patient_id})
            if patient:
                patient_name = patient.get('name', '')
        
        # 获取医生信息
        doctor_name = ''
        if 'doctorId' in order:
            doctor_id = order['doctorId']
            if isinstance(doctor_id, str) and ObjectId.is_valid(doctor_id):
                doctor_id = ObjectId(doctor_id)
            doctor = mongo.db.doctors.find_one({'_id': doctor_id})
            if doctor:
                doctor_name = doctor.get('name', '')
        
        # 标准化医嘱数据
        normalized_order = normalize_data(order)
        normalized_order['patientName'] = patient_name
        normalized_order['doctorName'] = doctor_name
        
        # 获取执行者信息
        if 'execution' in normalized_order and 'executedBy' in normalized_order['execution']:
            executor_id = normalized_order['execution']['executedBy']
            if executor_id:
                if isinstance(executor_id, str) and ObjectId.is_valid(executor_id):
                    executor_id = ObjectId(executor_id)
                executor = mongo.db.users.find_one({'_id': executor_id})
                if executor:
                    normalized_order['execution']['executedByName'] = executor.get('name', '')
        
        orders.append(normalized_order)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'orders': orders
        }
    }), 200

@api_bp.route('/medical-orders/<id>', methods=['GET'])
@jwt_required()
@permission_required('medical_order:read')
def get_medical_order(id):
    """获取医嘱详情"""
    # 查询医嘱
    medical_order = None
    if ObjectId.is_valid(id):
        medical_order = mongo.db.medical_orders.find_one({'_id': ObjectId(id)})
    
    if not medical_order:
        medical_order = mongo.db.medical_orders.find_one({'orderId': id})
    
    if not medical_order:
        return jsonify({
            'success': False,
            'message': '医嘱不存在'
        }), 404
    
    # 获取患者信息
    patient = None
    if 'patientId' in medical_order:
        patient_id = medical_order['patientId']
        if isinstance(patient_id, str) and ObjectId.is_valid(patient_id):
            patient_id = ObjectId(patient_id)
        patient = mongo.db.patients.find_one({'_id': patient_id})
    
    # 获取医生信息
    doctor = None
    if 'doctorId' in medical_order:
        doctor_id = medical_order['doctorId']
        if isinstance(doctor_id, str) and ObjectId.is_valid(doctor_id):
            doctor_id = ObjectId(doctor_id)
        doctor = mongo.db.doctors.find_one({'_id': doctor_id})
    
    # 标准化数据
    normalized_order = normalize_data(medical_order)
    
    # 添加患者信息
    if patient:
        normalized_order['patientInfo'] = {
            'id': str(patient['_id']),
            'patientId': patient.get('patientId', ''),
            'name': patient.get('name', ''),
            'gender': patient.get('gender', ''),
            'age': patient.get('age', '')
        }
    
    # 添加医生信息
    if doctor:
        normalized_order['doctorInfo'] = {
            'id': str(doctor['_id']),
            'staffId': doctor.get('staffId', ''),
            'name': doctor.get('name', ''),
            'title': doctor.get('title', '')
        }
    
    # 获取执行者信息
    if 'execution' in normalized_order and 'executedBy' in normalized_order['execution']:
        executor_id = normalized_order['execution']['executedBy']
        if executor_id:
            if isinstance(executor_id, str) and ObjectId.is_valid(executor_id):
                executor_id = ObjectId(executor_id)
            executor = mongo.db.users.find_one({'_id': executor_id})
            if executor:
                normalized_order['execution']['executedByInfo'] = {
                    'id': str(executor['_id']),
                    'name': executor.get('name', ''),
                    'role': executor.get('role', '')
                }
    
    return jsonify({
        'success': True,
        'data': normalized_order
    }), 200

@api_bp.route('/medical-orders', methods=['POST'])
@jwt_required()
@permission_required('medical_order:create')
def create_medical_order():
    """创建医嘱"""
    # 验证请求数据
    schema = MedicalOrderSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 验证患者是否存在
    patient_id = data.get('patientId')
    if not mongo.db.patients.find_one({'_id': ObjectId(patient_id)}):
        return jsonify({
            'success': False,
            'message': '患者不存在'
        }), 400
    
    # 验证医生是否存在
    doctor_id = data.get('doctorId')
    if not mongo.db.doctors.find_one({'_id': ObjectId(doctor_id)}):
        return jsonify({
            'success': False,
            'message': '医生不存在'
        }), 400
    
    # 生成医嘱ID
    order_type_prefix = 'LO' if data.get('type') == '长期医嘱' else 'TO'
    data['orderId'] = generate_id(order_type_prefix)
    
    # 设置创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    
    # 设置医嘱状态
    if 'status' not in data:
        data['status'] = '已开立'
    
    # 保存到数据库
    result = mongo.db.medical_orders.insert_one(data)
    
    # 获取相关信息用于返回
    patient = mongo.db.patients.find_one({'_id': ObjectId(patient_id)})
    patient_name = patient.get('name', '') if patient else ''
    
    doctor = mongo.db.doctors.find_one({'_id': ObjectId(doctor_id)})
    doctor_name = doctor.get('name', '') if doctor else ''
    
    return jsonify({
        'success': True,
        'message': '医嘱创建成功',
        'data': {
            'id': str(result.inserted_id),
            'orderId': data['orderId'],
            'patientName': patient_name,
            'doctorName': doctor_name,
            'type': data['type'],
            'status': data['status'],
            'createdAt': now.isoformat()
        }
    }), 201

@api_bp.route('/medical-orders/<id>', methods=['PUT'])
@jwt_required()
@permission_required('medical_order:update')
def update_medical_order(id):
    """更新医嘱"""
    # 查询医嘱
    medical_order = None
    if ObjectId.is_valid(id):
        medical_order = mongo.db.medical_orders.find_one({'_id': ObjectId(id)})
    
    if not medical_order:
        return jsonify({
            'success': False,
            'message': '医嘱不存在'
        }), 404
    
    # 验证请求数据
    schema = MedicalOrderUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 验证患者是否存在
    if 'patientId' in data:
        patient_id = data.get('patientId')
        if not mongo.db.patients.find_one({'_id': ObjectId(patient_id)}):
            return jsonify({
                'success': False,
                'message': '患者不存在'
            }), 400
    
    # 验证医生是否存在
    if 'doctorId' in data:
        doctor_id = data.get('doctorId')
        if not mongo.db.doctors.find_one({'_id': ObjectId(doctor_id)}):
            return jsonify({
                'success': False,
                'message': '医生不存在'
            }), 400
    
    # 医嘱执行后不能修改
    if medical_order.get('status') in ['已执行', '已停止']:
        return jsonify({
            'success': False,
            'message': '医嘱已执行或已停止，无法修改'
        }), 400
    
    # 更新时间
    data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    mongo.db.medical_orders.update_one({'_id': ObjectId(id)}, {'$set': data})
    
    return jsonify({
        'success': True,
        'message': '医嘱更新成功',
        'data': None
    }), 200

@api_bp.route('/medical-orders/<id>/execute', methods=['PUT'])
@jwt_required()
@permission_required('medical_order:execute')
def execute_medical_order(id):
    """执行医嘱"""
    # 查询医嘱
    medical_order = None
    if ObjectId.is_valid(id):
        medical_order = mongo.db.medical_orders.find_one({'_id': ObjectId(id)})
    
    if not medical_order:
        return jsonify({
            'success': False,
            'message': '医嘱不存在'
        }), 404
    
    # 验证医嘱状态
    if medical_order.get('status') != '已开立':
        return jsonify({
            'success': False,
            'message': f"医嘱当前状态为'{medical_order.get('status')}', 无法执行"
        }), 400
    
    # 准备执行信息
    now = datetime.datetime.utcnow()
    execution_data = {
        'executedBy': str(g.current_user['_id']),
        'executedAt': now,
        'note': request.json.get('note', '')
    }
    
    # 更新医嘱状态和执行信息
    mongo.db.medical_orders.update_one(
        {'_id': ObjectId(id)},
        {
            '$set': {
                'status': '已执行',
                'execution': execution_data,
                'updatedAt': now
            }
        }
    )
    
    return jsonify({
        'success': True,
        'message': '医嘱执行成功',
        'data': {
            'executedAt': now.isoformat(),
            'executedBy': str(g.current_user['_id']),
            'executedByName': g.current_user.get('name', '')
        }
    }), 200

@api_bp.route('/medical-orders/<id>/stop', methods=['PUT'])
@jwt_required()
@permission_required('medical_order:update')
def stop_medical_order(id):
    """停止医嘱"""
    # 查询医嘱
    medical_order = None
    if ObjectId.is_valid(id):
        medical_order = mongo.db.medical_orders.find_one({'_id': ObjectId(id)})
    
    if not medical_order:
        return jsonify({
            'success': False,
            'message': '医嘱不存在'
        }), 404
    
    # 验证医嘱状态
    if medical_order.get('status') == '已停止':
        return jsonify({
            'success': False,
            'message': '医嘱已经停止'
        }), 400
    
    # 准备停止信息
    now = datetime.datetime.utcnow()
    stop_data = {
        'stoppedBy': str(g.current_user['_id']),
        'stoppedAt': now,
        'reason': request.json.get('reason', '')
    }
    
    # 更新医嘱状态和停止信息
    mongo.db.medical_orders.update_one(
        {'_id': ObjectId(id)},
        {
            '$set': {
                'status': '已停止',
                'stop': stop_data,
                'updatedAt': now
            }
        }
    )
    
    return jsonify({
        'success': True,
        'message': '医嘱已停止',
        'data': {
            'stoppedAt': now.isoformat(),
            'stoppedBy': str(g.current_user['_id']),
            'stoppedByName': g.current_user.get('name', '')
        }
    }), 200

@api_bp.route('/patients/<id>/medical-orders', methods=['GET'])
@jwt_required()
@permission_required('medical_order:read')
def get_patient_medical_orders(id):
    """获取患者医嘱列表"""
    # 查找患者
    patient = None
    if ObjectId.is_valid(id):
        patient = mongo.db.patients.find_one({'_id': ObjectId(id)})
    
    if not patient:
        patient = mongo.db.patients.find_one({'patientId': id})
    
    if not patient:
        return jsonify({
            'success': False,
            'message': '患者不存在'
        }), 404
    
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'createdAt')
    order = request.args.get('order', 'desc')
    
    # 按类型筛选
    order_type = request.args.get('type')
    query = {'patientId': str(patient['_id'])}
    
    if order_type and order_type != 'all':
        query['type'] = order_type
    
    # 按状态筛选
    status = request.args.get('status')
    if status and status != 'all':
        query['status'] = status
    
    # 确定排序
    sort_direction = -1 if order.lower() == 'desc' else 1
    
    # 查询医嘱
    orders_cursor = mongo.db.medical_orders.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(orders_cursor, page, limit)
    
    # 标准化数据
    orders = []
    for order in paginated_data['items']:
        # 获取医生信息
        doctor_name = ''
        if 'doctorId' in order:
            doctor_id = order['doctorId']
            if isinstance(doctor_id, str) and ObjectId.is_valid(doctor_id):
                doctor_id = ObjectId(doctor_id)
            doctor = mongo.db.doctors.find_one({'_id': doctor_id})
            if doctor:
                doctor_name = doctor.get('name', '')
        
        # 标准化医嘱数据
        normalized_order = normalize_data(order)
        normalized_order['doctorName'] = doctor_name
        orders.append(normalized_order)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'orders': orders
        }
    }), 200

@api_bp.route('/doctors/<id>/medical-orders', methods=['GET'])
@jwt_required()
@permission_required('medical_order:read')
def get_doctor_medical_orders(id):
    """获取医生开立的医嘱列表"""
    # 查找医生
    doctor = None
    if ObjectId.is_valid(id):
        doctor = mongo.db.doctors.find_one({'_id': ObjectId(id)})
    
    if not doctor:
        doctor = mongo.db.doctors.find_one({'staffId': id})
    
    if not doctor:
        return jsonify({
            'success': False,
            'message': '医生不存在'
        }), 404
    
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'createdAt')
    order = request.args.get('order', 'desc')
    
    # 按类型筛选
    order_type = request.args.get('type')
    query = {'doctorId': str(doctor['_id'])}
    
    if order_type and order_type != 'all':
        query['type'] = order_type
    
    # 按状态筛选
    status = request.args.get('status')
    if status and status != 'all':
        query['status'] = status
    
    # 确定排序
    sort_direction = -1 if order.lower() == 'desc' else 1
    
    # 查询医嘱
    orders_cursor = mongo.db.medical_orders.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(orders_cursor, page, limit)
    
    # 标准化数据
    orders = []
    for order in paginated_data['items']:
        # 获取患者信息
        patient_name = ''
        if 'patientId' in order:
            patient_id = order['patientId']
            if isinstance(patient_id, str) and ObjectId.is_valid(patient_id):
                patient_id = ObjectId(patient_id)
            patient = mongo.db.patients.find_one({'_id': patient_id})
            if patient:
                patient_name = patient.get('name', '')
        
        # 标准化医嘱数据
        normalized_order = normalize_data(order)
        normalized_order['patientName'] = patient_name
        orders.append(normalized_order)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'orders': orders
        }
    }), 200